﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;

using GarageGames.Torque.Core;
using GarageGames.Torque.Util;
using GarageGames.Torque.Sim;
using GarageGames.Torque.T3D;
using GarageGames.Torque.SceneGraph;
using GarageGames.Torque.MathUtil;
using GarageGames.Torque.T3D.RigidCollision;
using GarageGames.Torque.Materials;

namespace TimeWar
{
    public abstract class AiObjectTemplate : TorqueObject, ITickObject
    {
        /// <summary>
        /// Allow developer to change the object type from template to regular Torque
        /// </summary>
        /// 
        [TorqueCloneIgnore]
        public bool TemplateFlag
        {
            get { return base.IsTemplate; }
            set { base.IsTemplate = value; }
        }

        public AiObjectTemplate()
        {
            //find the physics resolver
            RigidCollisionManager rigidManager = TorqueObjectDatabase.Instance.FindObject<RigidCollisionManager>("RigidManager");

            Name = "FriendlyTemplate";
            TemplateFlag = true;
            //TemplateFlag = false;

            //give the player a shape
            T3DTSRenderComponent componentRender = new T3DTSRenderComponent();
            componentRender.SceneGroupName = "FriendlyTemplate";
            componentRender.ShapeName = @"data\Characters\blue_player.dts";
            Components.AddComponent(componentRender);

            //give the player a presence within the scene
            T3DSceneComponent componentScene = new T3DSceneComponent();
            componentScene.SceneGroup = "FriendlyTemplate";
            componentScene.Position = new Vector3(1024, 1024, 300);
            Components.AddComponent(componentScene);

            //give the player some physics attributes, like gravity and collision
            //CollisionSphereShape collisionSphere = new CollisionSphereShape();
            //collisionSphere.Radius = 0.5f;
            T3DRigidComponent componentPhysics = new T3DRigidComponent();
            componentPhysics.SceneGroupName = "FriendlyTemplate";
            componentPhysics.GravityScale = 10f;
            componentPhysics.Mass = 10.0f;
            componentPhysics.RigidManager = rigidManager;
            //componentPhysics.CollisionBody.AddCollisionShape(collisionSphere);
            componentPhysics.CollisionBody.AddCollisionShape(new CollisionBoxShape());
            Components.AddComponent(componentPhysics);

            //add the animation component
            T3DAnimationComponent componentAnimation = new T3DAnimationComponent();
            componentAnimation.SceneGroupName = "FriendlyTemplate";
            Components.AddComponent(componentAnimation);

            //add the AI component
            //TorqueObject objPlayer = TorqueObjectDatabase.Instance.FindObject<TorqueObject>("PlayerObject");
            AiComponent componentAI = new AiComponent("FriendlyTemplate");
            //componentAI.Friendlies.Add(objPlayer);
            Components.AddComponent(componentAI);

            //add a simple shadow component
            T3DBlobShadowCasterComponent componentShadow = new T3DBlobShadowCasterComponent();
            componentShadow.SceneGroupName = "FriendlyTemplate";
            Components.AddComponent(componentShadow);

            //components so object can interact with other objects
            CollisionSphereShape sphereCollision = new CollisionSphereShape();
            sphereCollision.Radius = 5f;

            T3DTriggerComponent componentTrigger = new T3DTriggerComponent();
            componentTrigger.CollisionBody.AddCollisionShape(sphereCollision);
            componentTrigger.OnCollision = OnInProximity;
            componentTrigger.RigidManager = rigidManager;
            componentTrigger.Immovable = false;
            Components.AddComponent(componentTrigger);

            T3DGroundControlComponent componentGroundControl = new T3DGroundControlComponent();
            componentGroundControl.SceneGroupName = "FriendlyTemplate";
            componentGroundControl.ForceGravityOff = false;
            Components.AddComponent(componentGroundControl);

            //Mount the weapon
            T3DMountComponent componentMount = new T3DMountComponent();
            componentMount.SceneGroupName = "FriendlyTemplate";
            Components.AddComponent(componentMount);

            WeaponComponent3D weaponRifle = new WeaponComponent3D();
            weaponRifle.Name = "WeaponRifle";
            Components.AddComponent(weaponRifle);


        }

        /// <summary>
        /// Sets the name of the template and associates the appropriate components
        /// </summary>
        /// <param name="objName">The name of the template</param>
        public void SetName(string objName)
        {
            if (String.IsNullOrEmpty(objName))
            {
                return;
            }
            Name = objName;
            Components.FindComponent<T3DTSRenderComponent>().SceneGroupName = objName;
            Components.FindComponent<T3DSceneComponent>().SceneGroup = objName;
            Components.FindComponent<T3DRigidComponent>().SceneGroupName = objName;
            Components.FindComponent<T3DAnimationComponent>().SceneGroupName = objName;
            Components.FindComponent<AiComponent>().FriendlyName = objName;
            Components.FindComponent<T3DBlobShadowCasterComponent>().SceneGroupName = objName;
            Components.FindComponent<T3DTriggerComponent>().SceneGroupName = objName;
            Components.FindComponent<T3DGroundControlComponent>().SceneGroupName = objName;
            Components.FindComponent<T3DMountComponent>().SceneGroupName = objName;
            Components.FindComponent<WeaponComponent3D>().Name = objName + "Weapon";
        }

        /// <summary>
        /// Use this method to change the 3D model associated with this object
        /// </summary>
        /// <param name="fullPathToDtsModel">Full path and filename of DTS format model</param>
        public void SetShapeName(string fullPathToDtsModel)
        {
            if (String.IsNullOrEmpty(fullPathToDtsModel))
            {
                return;
            }
            Components.FindComponent<T3DTSRenderComponent>().ShapeName = fullPathToDtsModel;
        }

        public void InterpolateTick(float dt)
        {

        }

        public void ProcessTick(Move move, float dt)
        {
            //T3DGroundControlComponent groundControlComponent = Components.FindComponent<T3DGroundControlComponent>();

        }

        public override void CopyTo(TorqueObject obj)
        {
            //AiObjectTemplate obj2 = (AiObjectTemplate)obj;
            //obj2.TemplateFlag = TemplateFlag;
            obj.IsTemplate = false;
            base.CopyTo(obj);
            //obj.Components.AddComponent(Components.FindComponent<T3DTSRenderComponent>());
            //base.Components.FindComponent<T3DTSRenderComponent>().CopyTo(obj.Components.FindComponent<T3DTSRenderComponent>());
            //obj.Components.AddComponent(Components.FindComponent<T3DSceneComponent>());
            //obj.Components.AddComponent(Components.FindComponent<T3DRigidComponent>());
            base.Components.FindComponent<T3DRigidComponent>().CopyTo(obj.Components.FindComponent<T3DRigidComponent>());
            //obj.Components.AddComponent(Components.FindComponent<T3DAnimationComponent>());
            //obj.Components.AddComponent(Components.FindComponent<AiComponent>());
            //obj.Components.AddComponent(Components.FindComponent<T3DBlobShadowCasterComponent>());
            //obj.Components.AddComponent(Components.FindComponent<T3DTriggerComponent>());
            //obj.Components.AddComponent(Components.FindComponent<T3DGroundControlComponent>());
            //obj.Components.AddComponent(Components.FindComponent<T3DMountComponent>());
            //obj.Components.AddComponent(Components.FindComponent<WeaponComponent3D>());
        }


        /// <summary>
        /// Implement this method to determine what happens when another object enters within this object's proximity
        /// </summary>
        /// <param name="me">A T3DRigidComponent representing this object</param>
        /// <param name="you">A T3DRigidComponent representing the object in proximity</param>
        /// <param name="contacts"></param>
        /// <param name="contactCount">Number of contacts</param>
        /// <param name="dt">Time interval</param>
        public abstract void OnInProximity(T3DRigidComponent me, T3DRigidComponent you, RigidContactConstraint.Contact[] contacts, int contactCount, float dt);


        #region Private and protected methods


        #endregion Private and protected methods

    }
}
